import datetime
import math
import random
import sys
import time

from selenium.webdriver.common.by import By

from libs import config
from libs.action import WebDriverAction
from libs.game import Game
from libs.image import ImageTool
from libs.log import Log
from libs.movement import Movement
from libs.task_helper import TaskHelper
from libs.trade_helper import TradeHelper
from libs.window import AdsWindow

wines = {
    'popberry': {
        "skill_level": 0,
        "name": "Bottle of Popberry Wine",
        "sell_name": "Popberry Wine",
        "main_item": "Popberry",
        "items": {
            "Cooking Mix": 10,
            "Honey": 3,
            "Popberry": 36,
            "Silk Slug Slime": 1,
            "Glass Bottle": 1,
        },
        "energy_cost": 75,
        "wait_seconds": 60 * 60,
        "prepare": 4,
    },
    'popberry_12': {
        "skill_level": 0,
        "need_vip": True,
        "name": "12-Pack of Popberry Wine",
        "sell_name": "Popberry Wine",
        "main_item": "Popberry",
        "items": {
            "Cooking Mix": 10 * 12,
            "Honey": 3 * 12,
            "Popberry": 432,
            "Silk Slug Slime": 12,
            "Glass Bottle": 12,
        },
        "energy_cost": 810,
        "wait_seconds": 580 * 60,
        "prepare": 1,
    },
    'grainshine': {
        "skill_level": 2,
        "name": "Bottle of Grainshine",
        "sell_name": "Grainshine",
        "main_item": "Grainbow",
        "items": {
            "Cooking Mix": 10,
            "Honey": 3,
            "Grainbow": 8,
            "Silk Slug Slime": 1,
            "Glass Bottle": 1,
        },
        "energy_cost": 50,
        "wait_seconds": 64 * 60,
        "prepare": 4,
    },
    'grainshine_12': {
        "skill_level": 2,
        "need_vip": True,
        "name": "12-Pack of Grainshine",
        "sell_name": "Grainshine",
        "main_item": "Grainbow",
        "items": {
            "Cooking Mix": 10 * 12,
            "Honey": 3 * 12,
            "Grainbow": 96,
            "Silk Slug Slime": 1 * 12,
            "Glass Bottle": 1 * 12,
        },
        "energy_cost": 540,
        "wait_seconds": 608 * 60,
        "prepare": 1,
    },
    'grumpkin': {
        "skill_level": 10,
        "name": "Bottle of Blue Grumpkin Wine",
        "sell_name": "Blue Grumpkin Wine",
        "main_item": "Blue Grumpkin",
        "items": {
            "Cooking Mix": 10,
            "Honey": 3,
            "Blue Grumpkin": 16,
            "Silk Slug Slime": 1,
            "Glass Bottle": 1,
        },
        "energy_cost": 150,
        "wait_seconds": 77 * 60,
        "prepare": 4,
    },
    'grumpkin_5': {
        "skill_level": 10,
        "need_vip": True,
        "name": "5-Pack of Blue Grumpkin Wine",
        "sell_name": "Blue Grumpkin Wine",
        "main_item": "Blue Grumpkin",
        "items": {
            "Cooking Mix": 10 * 5,
            "Honey": 3 * 5,
            "Blue Grumpkin": 80,
            "Silk Slug Slime": 1 * 5,
            "Glass Bottle": 1 * 5,
        },
        "energy_cost": 676,
        "wait_seconds": 308 * 60,
        "prepare": 1,
    }
}


def choose_wine():
    is_vip = config.is_vip(user_id)
    energy = game.get_energy()
    can_make = []
    for key in wines:
        wine = wines.get(key)
        need_vip = wine.get('need_vip', False)
        if need_vip and not is_vip:
            continue
        need_energy = wine.get('energy_cost')
        if not has_wine and need_energy > energy: # 能量不足
            continue
        name = wine.get('sell_name')
        qty = game.get_backpack_qty(name)
        wine['qty'] = qty
        # 检查包里是否有主材料
        main_item = wine.get('main_item')
        if game.get_backpack_qty(main_item) >= wine.get('items', {}).get(main_item, 10):
            wine['has_main_item'] = 1
        can_make.append(wine)
    result = None
    if len(can_make) > 0:
        sorted_can_make = sorted(can_make, key=lambda x: (-x.get('has_main_item', 0), x.get('qty', 0), -x.get('energy_cost', 1000)))
        result = sorted_can_make[0]

    log.info(f'vip={is_vip}, energy={energy}, chose to make [{result.get('name')}]')
    return result


if __name__ == "__main__":
    parser = TaskHelper.default_args_parser('Wine')
    args = parser.parse_args()
    task_helper = TaskHelper.from_args(args)

    user_id = args.user_id
    log = Log(user_id)
    driver = AdsWindow(user_id).open(False)
    game = Game(driver, user_id)
    action = WebDriverAction(driver)
    movement = Movement(driver)
    image_tool = ImageTool(driver)
    trade_helper = TradeHelper(driver, user_id)

    game.enter_game()
    game.collect_mail()
    game.snapshot(user_id, 'before wine')

    if not config.get_account(user_id).get('wine', True):
        log.info('user configured not make wine')
        task_helper.task_fail()
        sys.exit()

    has_wine = game.has_wine()
    wine_config = choose_wine()
    if wine_config is None:
        task_helper.task_success()
        sys.exit()

    try:
        # 计算需要购买的材料数量
        energy = game.get_energy()
        energy_cost = wine_config.get('energy_cost', 1000)
        need_items = wine_config.get('items', {})

        prepare = wine_config.get('prepare', 1)
        buy_items = {}
        for item_name in need_items:
            inventory = game.get_backpack_qty(item_name)
            need_qty = need_items.get(item_name, 0)
            buy_qty = need_qty - inventory
            if buy_qty > 0:
                buy_items[item_name] = (need_qty - inventory) * prepare

        if len(buy_items) > 0:
            trade_helper.goto_buy_position()
            filter_input = trade_helper.open_market_buy()
            for buy_item_name in buy_items:
                buy_item_qty = buy_items.get(buy_item_name)
                trade_helper.market_buy_item(filter_input, buy_item_name, buy_item_qty)
            action.escape()
            time.sleep(0.5)
            action.escape()
            time.sleep(1)
        if game.get_energy() < energy_cost:
            home_loc = action.goto_spec()
            home_x, home_y = home_loc
            game.drink_wine(energy_cost + 100, home_x + 45, home_y + 180)

        wh_loc = None
        for _ in range(3):
            wh_loc = action.goto_wine_house()
            if wh_loc is None:
                wh_loc = action.goto_wine_house()
                time.sleep(2)
            else:
                break

        wh_x, wh_y = wh_loc
        click_x = wh_x + 50
        click_y = wh_y + 50
        action.click_by_offset(click_x, click_y)
        time.sleep(0.5)
        action.click_by_offset(click_x, click_y)
        time.sleep(0.5)
        cooking_item_name = wine_config.get('name')
        opt = action.find_element(By.XPATH, f"//span[text()='{cooking_item_name}']", cooking_item_name, 3)
        if opt is None:
            action.move_to('wine_house.png', delta_y=120, max_loop=3)
            time.sleep(1)
            wh_x, wh_y = image_tool.find_target('wine_house.png')
            action.click_by_offset(click_x, click_y)
            time.sleep(0.5)
            action.click_by_offset(click_x, click_y)
            opt = action.find_element(By.XPATH, f"//span[text()='{cooking_item_name}']", cooking_item_name, 10)
        opt.click()
        time.sleep(1)
        for _ in range(5):
            craft_button = action.find_element(By.CLASS_NAME, "Crafting_craftingButton__Qd6Ke", 'CraftButton', 2)
            if craft_button.text == 'In Progress':
                log.debug(f'wait 10 seconds')
                time.sleep(10)
                continue
            if craft_button.text == 'Collect':
                if craft_button.is_enabled():
                    craft_button.click()
                    time.sleep(2)
                else:
                    log.debug(f'wait 2 seconds')
                    time.sleep(2)
                    craft_button = action.find_element(By.CLASS_NAME, "Crafting_craftingButton__Qd6Ke", 'CraftButton',
                                                       2)
                    continue
            if craft_button.text == 'Create':
                if craft_button.is_enabled():
                    craft_button.click()
                    log.debug(f'make: {wine_config.get('name')}')
                    time.sleep(2)
                    break
                else:
                    break
        time.sleep(0.5)
        action.escape()
        time.sleep(0.5)

        game.snapshot(user_id, 'after wine')
        task_helper.task_success()

        energy_enough = game.get_energy() > energy_cost * 2
        if energy_enough or game.is_min_wine_enough(10):
            hour = datetime.datetime.now().hour

            delay_seconds = wine_config.get('wait_seconds')
            if int(user_id) % 24 == hour:
                delay_seconds = 60 * 60 * 8
            task_helper.wine(delay_seconds=delay_seconds)

    except Exception as e:
        task_helper.task_fail()
        task_helper.wine(retry=True)
        raise e
